package com.fjbdxk.beidou.core;


import java.io.UnsupportedEncodingException;

/**
 * 北斗标准语句格式：$<语句类型标识>，<数据字段>，<数据字段>，……，<数据字段>*<校验和><CR><LF>
 *北斗卫星通信协议中的报文结构
 * @author huanggy
 * @version 1.0.0
 * @date 2024/05/13
 **/
public abstract class AbstractBeiDouMessage {

    /**
     * 语句开始标识
     */
    public final static String BEGIN_CHAR = "$";

    /**
     * 北斗报文分隔符
     */
    public final static String SPLIT_CHAR = ",";

    /**
     * 校验合定界符
     */
    public final static String CHECK_CODE_CHAR = "*";

    /**
     * 终止符：<CR><LF>
     */
    public static final byte[] END_CODE_BYTE = new byte[]{13, 10};

    /**
     * 语句类型标识
     */
    public abstract String getType();

    /**
     * 数据字段内容
     */
    public abstract String getData();

    /***
     * 校验和<br/>
     * 语句中“$”和“*”之间（不含符号“$”和“*”）全部字符按字节异或的结果，前4bit和后4比特的16进制数分别以ASCII 码表示（0〜9, A〜F），高位在前。
     * 计算并返回报文的校验和
     */
    public String getCheckSum() {
        String data = getType() + SPLIT_CHAR + getData();//调用 getType() 和 getData() 方法获取报文的数据字段
        byte checkCode = 0;//初始化一个 checkCode 变量为 0，用于计算校验和
        for (byte b : data.getBytes()) {
            checkCode ^= b;
        }

        int firstFourBits = (checkCode >> 4) & 0xF;
        int lastFourBits = checkCode & 0xF;

        return Integer.toHexString(firstFourBits).toUpperCase() + Integer.toHexString(lastFourBits).toUpperCase();
    }

    /**
     * 获取消息，含结束符
     *构建并返回完整的报文字符串，包括起始符、数据、校验和和结束符。
     * @return
     */
    public String getMsg() {
        return BEGIN_CHAR
                + getType()
                + SPLIT_CHAR
                + getData()
                + CHECK_CODE_CHAR
                + getCheckSum()
                + new String(END_CODE_BYTE);
    }

    /**
     * 获取消息，含结束符
     *返回报文的字节数组表示。
     * @return
     */
    public byte[] getMshByte() {
        return getMsg().getBytes();
    }
}
